<template>
  <div>
    <div v-if="!readonly" style="text-align: right">
      <el-checkbox v-model="value.textMode" style="margin-right: 10px;" label="文本模式" @change="handleCheckboxChange" />
      <el-button-group style="margin-top: 0px; margin-right: 12px; margin-bottom: 4px;">
        <el-tooltip :open-delay="500" content="历史记录" placement="top">
          <el-button :disabled="element.id===undefined" icon="el-icon-link" size="mini" type="info" @click="handleHistory" />
        </el-tooltip>
        <el-tooltip content="下一个" placement="top" :open-delay="500">
          <el-button type="primary" icon="el-icon-right" size="mini" @click="next" />
        </el-tooltip>
        <el-tooltip content="保存并继续" placement="top" :open-delay="500">
          <el-button type="primary" icon-class="skill" size="mini" @click="saveTestCase(true)"><svg-icon icon-class="save-continuer" /></el-button>
        </el-tooltip>
        <el-tooltip content="保存" placement="top" :open-delay="500">
          <el-button type="primary" icon-class="skill" size="mini" @click="saveTestCase(false)"><svg-icon icon-class="save" /></el-button>
        </el-tooltip>
      </el-button-group>
    </div>
    <el-card shadow="hover" style="height: 75vh; overflow-y: scroll;">
      <el-form ref="element" size="small" class="demo-table-expand" :rules="rules" label-width="100px" label-position="left" :model="element" :disabled="readonly">
        <el-row :gutter="5">
          <el-form-item label="用例名称" prop="name">
            <el-col :span="24"> <el-input v-model="element.name" placeholder="请输入用例名称" /></el-col>
          </el-form-item>
          <el-form-item label="用例编号" prop="number">
            <el-col :span="17">
              <el-input v-model="element.number" placeholder="请输入用例编号" />
            </el-col>
            <el-col :span="4">
              <el-tooltip :open-delay="500" content="用例编写状态" placement="top">
                <el-select v-model="element.editStatus" placeholder="请选择用例编写状态" style="width: 100%">
                  <el-option v-for="item in editStatusOptions" :key="item.value" :label="item.name" :value="item.value" />
                </el-select>
              </el-tooltip>
            </el-col>
            <el-col :span="3">
              <el-tooltip :open-delay="500" content="优先级" placement="top">
                <el-select v-model="element.priority" placeholder="请选择优先级" style="width: 100%">
                  <el-option v-for="item in priorityOptions" :key="item.value" :label="item.name" :value="item.value" />
                </el-select>
              </el-tooltip>
            </el-col>
          </el-form-item>
        </el-row>
        <el-row :gutter="10">
          <el-form-item label="前提条件" prop="des">
            <el-col :span="24"><el-input v-model="element.before" placeholder="请输入前提条件" /></el-col>
          </el-form-item>
        </el-row>
        <div v-if="value.textMode">
          <el-row :gutter="10">
            <el-col :span="12">
              <label style="font-size: 14px; color: #606266;">操作步骤</label>
            </el-col>
            <el-col :span="12">
              <label style="font-size: 14px; color: #606266;">预期结果</label>
            </el-col>
          </el-row>
          <el-row :gutter="10">
            <el-col :span="12">
              <el-input v-model="element.steps[0].extra1" type="textarea" :autosize="{ minRows: 15 }" placeholder="请输入操作步骤" />
            </el-col>
            <el-col :span="12">
              <el-input v-model="element.steps[0].extra2" type="textarea" :autosize="{ minRows: 15 }" placeholder="请输入预期结果" />
            </el-col>
          </el-row>
        </div>
        <el-table
          v-else
          ref="stepsTable"
          border
          size="mini"
          :data="tableData"
        >
          <el-table-column type="index" align="center" width="60" label="编号" />
          <el-table-column prop="step" label="操作步骤" min-width="50%">
            <template v-slot="scope">
              <el-input v-if="scope.$index !== tableData.length - 1" v-model="scope.row.step" type="textarea" autosize class="item" />
              <el-input v-if="scope.$index === tableData.length - 1" v-model="scope.row.step" type="textarea" autosize class="item" @input="newTableRow()" />
            </template>
          </el-table-column>
          <el-table-column prop="result" label="预期结果" min-width="40%">
            <template v-slot="scope">
              <el-input v-if="scope.$index !== tableData.length - 1" v-model="scope.row.result" type="textarea" autosize class="item" />
              <el-input v-if="scope.$index === tableData.length - 1" v-model="scope.row.result" type="textarea" autosize class="item" @input="newTableRow()" />
            </template>
          </el-table-column>
          <el-table-column v-if="!readonly" align="center" label="操作" width="90px">
            <template v-slot="scope">
              <el-tooltip :tabindex="-1" content="插入行" placement="top" :open-delay="500">
                <el-button circle type="primary" size="mini" @click="addTableRow(scope.$index)"><i class="el-icon-plus" /></el-button>
              </el-tooltip>
              <el-tooltip :tabindex="-1" content="删除" placement="top" :open-delay="500">
                <el-button circle type="danger" size="mini" @click="delTableRow(scope.$index)"><i class="el-icon-close" /></el-button>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
    </el-card>

    <el-dialog :visible.sync="historyDialogFormVisible" title="历史记录" width="1200px" :close-on-click-modal="false">
      <test-case-history-component
        ref="testCaseHistoryComponent"
        @dblclickResultRow="dblclickResultRow"
      />
    </el-dialog>
  </div>
</template>

<style lang="scss">
  .item {
    .el-input__inner {
      border: 1px solid #fff !important;
      resize: none;
    }
    .el-textarea__inner {
      border: 1px solid #fff !important;
      resize: none;
    }
  }
</style>
<style>
  .icon-style {
    font-size: 15px;
  }
  .icon-wrapper {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    color: #606266;
    width: 20px;
    height: 20px;
  }
  .icon-wrapper:hover {
    color: #409EFF;
  }
  .icon-hover {
    color: #409EFF;
  }
  .icon-text {
    margin-left: 5px;
  }
</style>

<script>
import { selectById as testCaseSelectById, create as testCaseCreate, update as testCaseUpdate } from '@/api/functional_test/test_case_manage/test_case'
import TestCaseHistoryComponent from '@/components/functional_test/History/testCaseHistory'
import Sortable from 'sortablejs'
import { editStatusOptions } from '@/enum/editStatus.js'
import { priorityOptions } from '@/enum/priority.js'

export default {
  components: { TestCaseHistoryComponent },
  props: {
    value: {
      type: Object,
      default() {
        return {
          catalogId: 0, // 分类 id
          textMode: false // 文本模式编辑
        }
      }
    },
    // 是否只读
    readonly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      editStatusOptions, // 编写状态 options
      priorityOptions, // 优先级 options
      element: {}, // element 对象
      tableData: [],
      historyDialogFormVisible: false, // 历史记录弹窗
      rules: {
        number: [
          { max: 50, message: '测试用例编号长度不能超过 50 个字符', trigger: 'blur' }
        ],
        name: [
          { required: true, message: '测试用例名称不能为空', trigger: 'blur' },
          { max: 255, message: '测试用例名称长度不能超过 255 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  created() {
  },
  mounted() {
    this.rowDrop() // 支持行拖拽排序
  },
  methods: {
    rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        animation: 150, // 排序动画的时间，单位：ms
        onEnd({ newIndex, oldIndex }) {
          const currRow = _this.tableData.splice(oldIndex, 1)[0]
          _this.tableData.splice(newIndex, 0, currRow)

          // 重新赋值来刷新 table
          const newArray = _this.tableData.splice(0)
          _this.$nextTick().then(() => {
            _this.tableData = newArray
          })
        }
      })
    },
    // 新增时初始化 element 数据
    resetElement() {
      this.element = {
        projectId: this.$store.getters.projectId,
        catalogId: this.value.catalogId,
        caseType: 1,
        name: '',
        before: '',
        editStatus: 1,
        priority: 2,
        steps: [
          {
            projectId: this.$store.getters.projectId,
            extra1: '',
            extra2: '',
            error: 0
          }
        ]
      }
      this.tableData = []
      this.newTableRow()
    },
    // 设置 element 数据（当服务端返回数据后有些类型不符需要在这个方法中转换）
    setElement(ele) {
      this.element = ele
      // 如果设置成表格模式，改变到表格模式数据
      if (!this.value.textMode) {
        this.changeToTableMode()
      }
    },
    // 滚动到最下后新增一行表格数据
    newTableRow() {
      this.tableData.push({
        step: '',
        result: ''
      })
      this.$nextTick(() => { // table 超出后滚动到最后
        this.$refs.stepsTable.bodyWrapper.scrollTop = this.$refs.stepsTable.bodyWrapper.scrollHeight
      })
    },
    // 装载数据
    loadData(id) {
      testCaseSelectById(id).then(response => {
        this.setElement(response.data)
      })
    },
    // 点击新增用例按钮时调用此方法
    add() {
      this.resetElement()
    },
    // 文本模式 改变调用此方法
    handleCheckboxChange(val) {
      if (val) {
        this.changeToTextMode()
      } else {
        this.changeToTableMode()
        this.$nextTick().then(() => {
          this.rowDrop() // 支持行拖拽排序
        })
      }
    },
    // 改变到文本模式
    changeToTextMode() {
      // 循环遍历表格数据，把 step 信息放到 steps 中，把 result 数据放到 results 中
      let steps = ''
      let results = ''
      this.tableData.forEach(function(item, index, arr) {
        steps = steps + item.step + '\n'
        results = results + item.result + '\n'
      })
      // 去掉最后多余换行放到 element 对象中
      this.element.steps[0].extra1 = steps.trimEnd()
      this.element.steps[0].extra2 = results.trimEnd()
    },
    // 改变到表格模式
    changeToTableMode() {
      // 将文本按照 \n 分割成数组
      const steps = this.element.steps[0].extra1.trimEnd().split(/[\n]/)
      const results = this.element.steps[0].extra2.trimEnd().split(/[\n]/)

      // 以 steps results 这两最大的当 arrLength
      let arrLength = 0
      steps.length >= results.length ? arrLength = steps.length : arrLength = results.length

      // 遍历 steps results 生成 表格数据
      const tempTableData = []
      for (let i = 0; i < arrLength; i++) {
        const tempRow = {}
        if (steps.length > i) {
          tempRow.step = steps[i]
        } else {
          tempRow.step = ''
        }
        if (results.length > i) {
          tempRow.result = results[i]
        } else {
          tempRow.result = ''
        }
        tempTableData.push(tempRow)
      }

      // 替换原来的表格数据
      this.tableData = tempTableData
      // 最后补一个空行
      if ((steps[steps.length - 1].length !== 0 || results[results.length - 1].length !== 0)) {
        this.newTableRow()
      }
    },
    // 插入 table 中的一行数据
    addTableRow(index) {
      this.tableData.splice(index + 1, 0, { step: '', result: '' }) // 插入一行
    },
    // 删除 table 中的一行数据
    delTableRow(index) {
      this.tableData.splice(index, 1) // 删除一行
    },
    /**
     * 保存 测试用例
     * @param saveAndContinue 保存继续时，要传入 tree
     */
    saveTestCase(saveAndContinue) {
      this.$refs['element'].validate((valid) => {
        if (valid) {
          this.element.type = 1 // 分类 type，1 手工测试用例
          this.element.caseType = 1 // 用例 type，1 手工用例
          if (!this.value.textMode) { // 表格编辑模式时，点击保存时先将数据，改变到文本模式
            this.changeToTextMode()
          }
          if (!this.element.id || this.element.id === 0) { // id = 0，新增
            if (!this.element.catalogId) { // 跟目录设置 parentId = 0
              this.element.catalogId = 0
            }
            testCaseCreate(this.element).then((response) => {
              if (saveAndContinue) { // 保存并继续
                this.resetElement()
              } else { // 保存
                this.element = response.data
              }
              this.$emit('create', response.data)
              this.$message({ message: '添加成功!', type: 'success' })
            })
          } else { // 否则修改
            testCaseUpdate(this.element).then((response) => {
              if (saveAndContinue) { // 保存并继续
                this.$emit('updateNext', response.data)
              } else { // 保存
                this.$emit('update', response.data)
              }
              this.$message({ message: '修改成功!', type: 'success' })
            })
          }
        }
      })
    },
    // 下一个 tree 节点
    next() {
      this.$emit('next')
    },
    // 点击 history 按钮
    handleHistory() {
      this.historyDialogFormVisible = true
      this.$nextTick(() => {
        this.$refs.testCaseHistoryComponent.loadData(this.element.id)
      })
    },
    // 双击历史结果行
    dblclickResultRow(ele) {
      this.historyDialogFormVisible = false
      this.setElement(ele)
    }
  }
}
</script>
